<!doctype html>
<html lang="zh-CN"><head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
    <title>薛尧的博客</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="" />

    
    
    
    <link rel="stylesheet" href="../../../css/theme.min.css">

    
    
    
    
    <link rel="stylesheet" href="../../../css/custom.min.css">
    

    
</head>
<body>
        <div id="content" class="mx-auto"><header class="container mt-sm-5 mt-4 mb-4 mt-xs-1">
    <div class="row">
        
        <div class="col-sm-4 col-12 text-sm-right text-center pt-sm-4">
            <a href="../../../" class="text-decoration-none">
                <img id="home-image" class="rounded-circle"
                    
                        src="https://ueyao.github.io/image-hosting/blog/avatar.png"
                    
                />
            </a>
        </div>
        <div class="col-sm-8 col-12 text-sm-left text-center">
        
            <h2 class="m-0 mb-2 mt-4">
                <a href="../../../" class="text-decoration-none">
                    
                        薛尧
                    
                </a>
            </h2>
            <p class="text-muted mb-1">
                
                    Java Developer | Short Video Creator
                
            </p>
            <ul id="nav-links" class="list-inline mb-2">
                
                
                    <li class="list-inline-item">
                        <a class="badge badge-white " href="../../../about/" title="关于">关于</a>
                    </li>
                
                    <li class="list-inline-item">
                        <a class="badge badge-white " href="../../../post/" title="文章">文章</a>
                    </li>
                
                    <li class="list-inline-item">
                        <a class="badge badge-white " href="../../../categories/" title="分类">分类</a>
                    </li>
                
            </ul>
            <ul id="nav-social" class="list-inline">
                
                    <li class="list-inline-item mr-3">
                        <a href="http://github.com/flowstone" target="_blank">
                            <i class="fab fa-github fa-1x text-muted"></i>
                        </a>
                    </li>
                
                    <li class="list-inline-item mr-3">
                        <a href="mailto:xueyao.me#gmail.com" target="_blank">
                            <i class="fas fa-at fa-1x text-muted"></i>
                        </a>
                    </li>
                
            </ul>
        </div>
    </div>
    <hr />
</header>
<div class="container">
    <div class="pl-sm-2">
        <div class="mb-3">
            <h3 class="mb-0">代码优化-多态代替IF条件判断</h3>
            
            <small class="text-muted">发布于 2019-12-01</small>
        </div>

        <article>
            <h2 id="场景描述">场景描述</h2>
<p>在开发的场景中，常常会遇到打折的业务需求，每个用户对应的等级，他们的打折情况也是不一样的。例如普通会员打9折，青铜会员打8.5折，黄金会员打8折等等。在一般开发中最简单的就是判断用户的等级，然后对订单作对应的打折处理。</p>
<h2 id="场景示例">场景示例</h2>
<p>写了一个简单的小示例，如下所示：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#75715e">//1 代表学生 2老师   3校长</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> type <span style="color:#f92672">=</span> 1;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (1 <span style="color:#f92672">==</span> type) {
</span></span><span style="display:flex;"><span>    System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;学生笑嘻嘻的说话&#34;</span>);
</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (2 <span style="color:#f92672">==</span> type) {
</span></span><span style="display:flex;"><span>    System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;老师开心的说话&#34;</span>);
</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>    System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;校长严肃的说话&#34;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>上面的代码，是我们经常的做法，代码少的时候，看起来非常清晰，但是代码多起来或者有了更多的判断条件，那上面的代码会更加的混乱，如果每次有修改，都要改动这部分代码。</p>
<h2 id="解决方法">解决方法</h2>
<p>可以把上面的代码改成多态方式，创建三个类，学生Student,老师Teacher,校长HeadMater，父类为Person，这三个类都实现父类的方法say，如下所示:</p>
<p>Person.class</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> me.xueyao.service;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @author Simon.Xue
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @date 2019-12-01 14:31
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> **/</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">Person</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">say</span>();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Student.class</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> me.xueyao.service.impl;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> me.xueyao.service.Person;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.stereotype.Service;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @author Simon.Xue
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @date 2019-12-01 14:34
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> **/</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Service</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Student</span> <span style="color:#66d9ef">implements</span> Person {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Override</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">say</span>() {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;学生笑嘻嘻的说话&#34;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Teacher.class</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> me.xueyao.service.impl;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> me.xueyao.service.Person;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.stereotype.Service;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @author Simon.Xue
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @date 2019-12-01 14:37
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> **/</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Service</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Teacher</span> <span style="color:#66d9ef">implements</span> Person {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Override</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">say</span>() {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;老师开心的说话&#34;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>HeadMaster.class</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> me.xueyao.service.impl;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> me.xueyao.service.Person;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.stereotype.Service;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @author Simon.Xue
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @date 2019-12-01 14:41
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> **/</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Service</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">HeadMaster</span> <span style="color:#66d9ef">implements</span> Person {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Override</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">say</span>() {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;校长严肃的说话&#34;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>测试方法</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@Test</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testSay</span>() {
</span></span><span style="display:flex;"><span>    Person student <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Student();
</span></span><span style="display:flex;"><span>    student.<span style="color:#a6e22e">say</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    Person teacher <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Teacher();
</span></span><span style="display:flex;"><span>    teacher.<span style="color:#a6e22e">say</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    Person headMaster <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> HeadMaster();
</span></span><span style="display:flex;"><span>    headMaster.<span style="color:#a6e22e">say</span>();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="优化">优化</h2>
<p>上面的这种做法，基本上是完成了优化，但是我们还会发现了一个问题，就是每次我们还是要创建对应的对象。上面有三个类，我们就要创建有三个对象，能否再次优化一下？</p>
<p>因为现在项目用Sping框架，所以可以用注入来完成优化。</p>
<p>首先，创建一个Person枚举类,如下所示：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> me.xueyao.enums;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> lombok.AllArgsConstructor;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> lombok.Getter;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> me.xueyao.service.impl.HeadMaster;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> me.xueyao.service.impl.Student;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> me.xueyao.service.impl.Teacher;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @author Simon.Xue
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @date 2019-12-01 15:55
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> **/</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@AllArgsConstructor</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Getter</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">enum</span>  PersonEnums {
</span></span><span style="display:flex;"><span>    STUDENT(1, <span style="color:#e6db74">&#34;学生&#34;</span>, Student.<span style="color:#a6e22e">class</span>),
</span></span><span style="display:flex;"><span>    TEACHER(2, <span style="color:#e6db74">&#34;老师&#34;</span>, Teacher.<span style="color:#a6e22e">class</span>),
</span></span><span style="display:flex;"><span>    HEADMASTER(3, <span style="color:#e6db74">&#34;校长&#34;</span>, HeadMaster.<span style="color:#a6e22e">class</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    Integer code;
</span></span><span style="display:flex;"><span>    String msg;
</span></span><span style="display:flex;"><span>    Class clazz;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">     * 获得类的名称，因为Spring自动注入时，默认名称是类名(首字母小写)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">     * @param code
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">     * @return
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> String <span style="color:#a6e22e">className</span>(Integer code) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> (PersonEnums value : values()) {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (value.<span style="color:#a6e22e">getCode</span>().<span style="color:#a6e22e">equals</span>(code)) {
</span></span><span style="display:flex;"><span>                String simpleName <span style="color:#f92672">=</span> value.<span style="color:#a6e22e">getClazz</span>().<span style="color:#a6e22e">getSimpleName</span>();
</span></span><span style="display:flex;"><span>                simpleName.<span style="color:#a6e22e">substring</span>(1);
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">return</span> String.<span style="color:#a6e22e">valueOf</span>(simpleName.<span style="color:#a6e22e">charAt</span>(0)).<span style="color:#a6e22e">toLowerCase</span>() <span style="color:#f92672">+</span> simpleName.<span style="color:#a6e22e">substring</span>(1);
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;&#34;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>使用方式 ：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@Autowired</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">private</span> Map<span style="color:#f92672">&lt;</span>String, Person<span style="color:#f92672">&gt;</span> personMap <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> HashMap<span style="color:#f92672">&lt;&gt;</span>();
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Test</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testSay</span>() {
</span></span><span style="display:flex;"><span>    personMap.<span style="color:#a6e22e">get</span>(PersonEnums.<span style="color:#a6e22e">className</span>(2)).<span style="color:#a6e22e">say</span>();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>
        </article>
    </div>

    <div id="disqus_thread"></div>
<script>
    window.disqus_config = function () {
    
    
    
    };
    (function() {
        if (["localhost", "127.0.0.1"].indexOf(window.location.hostname) != -1) {
            document.getElementById('disqus_thread').innerHTML = 'Disqus comments not available by default when the website is previewed locally.';
            return;
        }
        var d = document, s = d.createElement('script'); s.async = true;
        s.src = '//' + "xie-yao-de-bo-ke" + '.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="https://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>

            </div>
        </div><footer class="text-center pb-1">
    <small class="text-muted">
        
        &copy; Copyright 2024
        
        |
        <a href="https://beian.miit.gov.cn/" target="_blank">苏ICP备14012079号</a>
        <br />
        由 <a href="https://gohugo.io/" target="_blank">Hugo</a> 强力驱动
        | 主题 <a href="https://github.com/austingebauer/devise" target="_blank">Devise</a>
        <br />

    </small>
</footer></body>
</html>
